<template>
  <ve-popup :model-value="modalVisible" @close="close" :maskClose="false" style="z-index: 9999" mode="right">
    <view class="container">
      <view class="header">
        <ve-navbar :title="selector.config.listPage.title" :autoBack="false" @leftClick="close">
          <template #right>
            <view class="header-right" @click="onRightClick" v-if="operation">
              <ve-icon name="plus" size="36"></ve-icon>
              新增车型
            </view>
          </template>
        </ve-navbar>
      </view>
      <ve-search-bar
        :showBorder="true"
        v-if="selector.config.search !== false"
        :placeholder="selector.config.listPage.placeholder"
        @search="getList"
      ></ve-search-bar>

      <view class="content">
        <!-- 交还车人展示OTA同步过来的姓名 -->
        <!-- 目前仅短长租订单，编辑交还车人会触发这个“无法匹配”的展示，后续完善 -->
        <view class="staffName" v-if="selector.config.component == 'staff' && selector.params.staffName && !selector.params.oldId">
          {{ selector.params.staffName }}（无法匹配）
        </view>
        <scroll-view class="scroll-car" scroll-y @touchmove.stop>
          <template v-for="item in list" :key="item.key">
            <StaffItem v-if="selector.config.component == 'staff'" :record="item" :selected="setSelected(item)" @click="chooseItem(item)">
            </StaffItem>
            <Default v-else :record="item" :selected="setSelected(item)" @click="chooseItem(item)"> </Default>
          </template>
          <view style="height: 38rpx"></view>
          <ve-empty text="没有数据~" v-if="list.length == 0"></ve-empty>
        </scroll-view>
      </view>
    </view>

    <ve-bottom-box size="mini">
      <ve-button type="primary" @click="onConfirm" size="long">{{ btnText }}</ve-button>
    </ve-bottom-box>
  </ve-popup>
</template>

<script lang="ts" setup>
  import { ref, reactive, watch } from 'vue'
  import Configs from './configs'
  import Default from './items/default.vue'
  import StaffItem from './items/staff.vue'
  import { onBackPress } from '@dcloudio/uni-app'

  const emits = defineEmits(['close', 'rightClick', 'change'])

  const props = defineProps({
    btnText: {
      type: String,
      default: '确认',
    },
    operation: {
      type: Boolean,
      default: false,
    },
    secondModal: {
      type: Boolean,
      default: false,
    },
    registerOnBackPressEvent: {
      type: Boolean,
      default: true,
    },
  })
  const modalVisible = ref(false)
  const selector = reactive({
    config: {},
    params: {},
    prop: undefined,
  })

  const selectValue = ref()
  // 是否是多选
  const isMultiple = ref(false)
  const open = (data: any) => {
    modalVisible.value = true
    const config = Configs[data.type]
    selector.config = {
      ...config,
      ...data.config,
    }
    selector.prop = data.prop
    selector.params = { ...config.params, ...data.params }
    selectValue.value = data.value
    isMultiple.value = data.multiple
    // 获取列表, 外部传入，或调api
    if (data.outData) {
      getData(data.outData)
      return
    }
    getList()
  }
  const close = () => {
    modalVisible.value = false
    emits('close')
  }

  watch(
    () => modalVisible.value,
    (val) => {
      if (val) {
        uni.hideTabBar()
      } else {
        uni.showTabBar()
      }
    },
  )
  // 是否注册 onBackPress 的方法
  if (props.registerOnBackPressEvent) {
    // 截获左滑右滑
    onBackPress(() => {
      if (modalVisible.value == true) {
        modalVisible.value = false
        emits('close')
        // 阻止默认事件
        return true
      }
    })
  }
  const list = ref([])
  const getData = (data) => {
    list.value = data.map((item: any) => {
      const config = selector.config as any
      const sitem = {
        key: item[config.key],
        label: item[config.label],
        desc: undefined,
        option: item,
      }
      if (config.desc) {
        sitem.desc = item[config.desc]
      }
      return sitem
    })
  }
  const getList = (keyword = undefined) => {
    const queryParam = {
      ...selector.params,
    }
    queryParam[selector.config.keyword] = keyword
    selector.config.api(queryParam).then((res: any) => {
      if (res.code == 200) {
        list.value = res.result.map((item: any) => {
          const config = selector.config as any
          const sitem = {
            key: item[config.key],
            label: item[config.label],
            desc: undefined,
            option: item,
          }
          if (config.desc) {
            sitem.desc = item[config.desc]
          }
          return sitem
        })
      }
    })
  }

  const onRightClick = () => {
    emits('rightClick')
  }

  const setSelected = (item: any) => {
    if (!selectValue.value) return false
    if (Array.isArray(selectValue.value)) {
      return selectValue.value.includes(item.key)
    } else if (item.key == selectValue.value) {
      return true
    }
    return false
  }

  // 选中一个
  const chooseItem = (record: any) => {
    if (isMultiple.value) {
      if (!selectValue.value) {
        selectValue.value = [record.key]
      }
      const index = selectValue.value.findIndex((it: any) => it == record.key)
      if (index == -1) {
        selectValue.value.push(record.key)
      } else {
        selectValue.value.splice(index, 1)
      }
    } else {
      selectValue.value = record.key
    }
  }

  const onConfirm = () => {
    if (isMultiple.value) {
      const selectedList = list.value.filter((it: any) => {
        return selectValue.value.includes(it.key)
      })
      const label = selectedList.map((it: any) => it.label).join(' | ')
      const options = selectedList.map((it: any) => it.option)
      emits('change', selectValue.value, label, options)
    } else {
      const record = list.value.find((item: any) => item.key == selectValue.value)
      emits('change', selectValue.value, record.label, record.option)
    }

    if (props.secondModal) {
      return
    }
    modalVisible.value = false
    emits('close')
  }

  defineExpose({ open, modalVisible })
</script>

<style lang="less" scoped>
  .container {
    height: 100vh;
    width: 100%;
    background: #f7f8fa;

    .header {
      position: relative;
      background: #ffffff;
      text-align: center;
      .back-btn {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 24px;
      }

      &-right {
        display: flex;
        align-items: center;
        font-size: 30rpx;
        font-weight: 400;
        color: #165dff;

        .svg-icon {
          margin-right: 8rpx;
        }
      }
    }

    .content {
      height: 86vh;
      padding-top: 1px;
      /* #ifdef H5 */
      padding-bottom: 152rpx;
      /* #endif */
      /* #ifdef APP-PLUS */
      padding-bottom: 152rpx;
      /* #endif */

      .staffName {
        display: flex;
        flex-direction: column;
        background: #ffffff;
        border-radius: 8rpx;
        padding: 32rpx;
        margin: 24rpx 24rpx 0;
        font-size: 30rpx;
        color: #191c27;
        word-break: break-all;
        font-weight: 600;
      }
    }
  }

  .client-item {
    position: relative;
    background: #ffffff;
    box-shadow: 0rpx 0rpx 30rpx 0rpx rgba(0, 0, 0, 0.05);
    border-radius: 8rpx;
    padding: 32rpx;
    margin: 24rpx;

    .choose {
      position: absolute;
      top: 36rpx;
      right: 32rpx;
    }

    .m_name {
      font-weight: 600;
      color: rgba(0, 0, 0, 0.85);
      line-height: 44rpx;
      font-size: 32rpx;
    }

    .m_phone {
      margin-top: 16rpx;
      font-size: 28rpx;
      font-weight: 400;
      color: #8491a8;
      line-height: 40rpx;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }
  }
</style>
